#!/usr/bin/env python
"""
Verifies the validity of the host certificate. The certificate needs not 
to be a grid-certificate. Therefore no checks on the usual trustanchors
(like /etc/grid-security/certificate etc.) .


 -c : critical certificate expiration threshold in hours (24 hours default)
 -w : warning certificate expiration threshold in hours (96 hours (4days) default)

(no check whether c values <= w values)
"""
# last change: bug-fix for 1.38 IGTF bundle 

__author__  = "Placi Flury grid@switch.ch"
__copyright__ = "Copyright 2010, SMSCG an AAA/SWITCH project"
__date__ = "18.07.2011"
__version__ = "0.1.0"

import commands 
import sys, time, calendar
from M2Crypto import X509, m2   # python-m2crypto package >= 0.17 
import os.path 
from nagios_plugin import NagiosPluginBasic, RETURN_CODE

HOSTCERT = "/etc/grid-security/hostcert.pem"

class HostCert(NagiosPluginBasic):
    """
    Checks IGTF trust anchors.
    """
    def __init__(self):
        NagiosPluginBasic.__init__(self)
        self.version = 0.0
        parser = NagiosPluginBasic.getOptions(self)
        parser.remove_option("-H")   # remove hostname option
        parser.add_option("-C", "--crl_critical", action="store",
                            dest="crl_critical_thresh", type="float",
                            default="2.0", help="Critial threshold in hours before CRL expiration. [default= %default]")

        parser.add_option("-W", "--crl_warning", action="store",
                            dest="crl_warning_thresh", type="float",
                            default="12.0", help="Warning threshold in hours before CRL expiration. [default= %default]")
        self.options = parser.parse_args()[0]
        
        if not self.options.critical_thresh:
            self.options.critical_thresh = 24 # 24 hours 
        if not self.options.warn_thresh:
            self.options.warn_thresh = 96 # 96 hours = 4 days 
        
    
        self.options.critical_thresh = float(self.options.critical_thresh)  # still net to cast them ;-(
        self.options.warn_thresh = float(self.options.warn_thresh) 
        self.options.crl_critical_thresh = float(self.options.crl_critical_thresh) 
        self.options.crl_warning_thresh = float(self.options.crl_warning_thresh) 
    
    def check_hostcert(self):
        # check whether both exist
        if not os.path.exists(HOSTCERT) or not os.path.isfile(HOSTCERT):
            print "CRITICAL: hostcertificate file '%s' does not exist." % (HOSTCERT)
            sys.exit(RETURN_CODE["critical"])
        
        
        # check whether can read hostcert
        if not os.access(HOSTCERT, os.R_OK):
            print "CRITICAL: Failed while reading host certificate '%s'. Permission denied." % HOSTCERT
            sys.exit(RETURN_CODE["critical"])

        # check expiration time
        try:
            x509 = X509.load_cert(HOSTCERT, X509.FORMAT_PEM)
            enddate = x509.get_not_after().__str__()
        except Exception, e:
            print  'UNKNOWN: %r' % e
            sys.exit(RETURN_CODE["unknown"])
    
        enddate_tuple = time.strptime(enddate, '%b %d %H:%M:%S %Y GMT')
        enddate_epoch = calendar.timegm(enddate_tuple)
        secs2exp = enddate_epoch - time.mktime(time.localtime())
        hours2exp = secs2exp/3600.0

        if self.options.critical_thresh > hours2exp:
            print "CRITICAL: hostcert expires in %d hours (%0.2f days)" % (hours2exp, hours2exp/24)
            sys.exit(RETURN_CODE["critical"])
        elif (self.options.warn_thresh > hours2exp):
            print "WARNING: hostcert expires in %d hours (%0.2f days)" % (hours2exp, hours2exp/24)
            sys.exit(RETURN_CODE["warning"])

    def main(self):
        self.check_hostcert()



if __name__ == "__main__":
    ta = HostCert()
    ta.main()
    print "OK: valid hostcert"
    sys.exit(RETURN_CODE["ok"])


